package com.google.gwt.maps.v3.sample.client.presenter;

import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.maps.v3.client.HasMap;
import com.google.gwt.maps.v3.client.base.HasLatLng;
import com.google.gwt.maps.v3.client.base.LatLng;
import com.google.gwt.maps.v3.client.event.Event;
import com.google.gwt.maps.v3.client.event.EventCallback;
import com.google.gwt.maps.v3.client.event.HasMouseEvent;
import com.google.gwt.maps.v3.client.event.MouseEventCallback;
import com.google.gwt.maps.v3.client.overlay.HasMarker;
import com.google.gwt.maps.v3.client.overlay.Marker;
import com.google.gwt.maps.v3.client.streetview.HasStreetViewPanorama;
import com.google.gwt.maps.v3.client.streetview.HasStreetViewPanoramaData;
import com.google.gwt.maps.v3.client.streetview.HasStreetViewPov;
import com.google.gwt.maps.v3.client.streetview.HasStreetViewService;
import com.google.gwt.maps.v3.client.streetview.StreetViewPanorama;
import com.google.gwt.maps.v3.client.streetview.StreetViewPov;
import com.google.gwt.maps.v3.client.streetview.StreetViewService;
import com.google.gwt.maps.v3.client.streetview.StreetViewServiceCallback;
import com.google.gwt.maps.v3.sample.client.Constant;
import com.google.gwt.maps.v3.sample.client.view.SampleView;
import com.google.gwt.user.client.Element;

public class StreetViewServicePresenter implements Presenter<StreetViewServicePresenter.Display> {

  public static interface Display extends SampleView {
    Element getPanoContainer();
    HasMap getMap();
    void alert(String msg);
  }
  
  final private Display display;
  final private String presenterLink;
  final private String viewLink;
  
  private HasStreetViewPanorama panorama;
  
  public StreetViewServicePresenter(final Display display) {
    super();
    this.display = display;
    presenterLink = Constant.SOURCE_URL_PREFIX
        + this.getClass().getName().replace('.', '/') + ".java";
    viewLink = Constant.SOURCE_URL_PREFIX
        + display.getClass().getName().replace('.', '/') + ".java";
  }

  @Override
  public void bind() {
    display.setPresenterLink(presenterLink);
    display.setViewLink(viewLink);
    
    final HasLatLng berkeley = new LatLng(37.869085, -122.254775);
    final HasStreetViewService sv = new StreetViewService();
    panorama = new StreetViewPanorama(display.getPanoContainer());
    
    MouseEventCallback mapClickCallback = new MouseEventCallback() {
      
      @Override
      public void callback(HasMouseEvent event) {
        sv.getPanoramaByLocation(event.getLatLng(), 50, new StreetViewServiceCallback() {
          
          @Override
          public void callback(HasStreetViewPanoramaData data, String status) {
            processSvData(data, status);
          }
        });
      }
    };
    Event.addListener(display.getMap(), "click", mapClickCallback);
    
  }

  @Override
  public Display getDisplay() {
    return display;
  }

  @Override
  public HandlerManager getEventBus() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void release() {
    // TODO Auto-generated method stub
    
  }
  
  private void processSvData(final HasStreetViewPanoramaData data, final String status) {
    if (status.equals("OK")) {
      HasMarker marker = new Marker();
      marker.setPosition(data.getLocation().getLatLng());
      marker.setTitle(data.getLocation().getDescription());
      marker.setMap(display.getMap());
      
      panorama.setPano(data.getLocation().getPano());
      final HasStreetViewPov pov = new StreetViewPov();
      pov.setHeading(34);
      pov.setPitch(10);
      pov.setZoom(1);
      panorama.setPov(pov);
      panorama.setVisible(true);
      
      EventCallback markerClickCallback = new EventCallback() {
        
        @Override
        public void callback() {
          panorama.setPano(data.getLocation().getPano());
          final HasStreetViewPov pov = new StreetViewPov();
          pov.setHeading(270);
          pov.setPitch(0);
          pov.setZoom(1);
          panorama.setPov(pov);
          panorama.setVisible(true);
        }
      };
      Event.addListener(marker, "click", markerClickCallback);
    } else {
      display.alert("Street View data not found for this location.");
    }
  }
}
